package com.suzj.extraenchantments.util;

import com.google.common.collect.Sets;
import java.util.Set;
import java.util.function.BiConsumer;
import javax.annotation.Nullable;

import net.minecraft.client.resources.model.Material;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.tags.BlockTags;
import net.minecraft.util.RandomSource;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.enchantment.EnchantmentHelper;
import net.minecraft.world.item.enchantment.Enchantments;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.Blocks;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.material.MapColor;


public class MiningHelper {
    public static void harvestCube(Level world, Player player, Direction dir, BlockPos centralPos, Set<MapColor> effectiveMaterials, int planeRadius, int depth, boolean harvestLevelCheck, @Nullable BlockPos excludedBlock, ItemStack tool, BiConsumer<BlockPos, BlockState> toolDamageConsumer) {
        for (int a = 0; a < depth; a++) {
            int x = 0;
            int y = 0;
            int z = 0;
            if (dir == Direction.UP) {
                y = 0 - a;
            }
            if (dir == Direction.DOWN) {
                y += a;
            }
            if (dir == Direction.SOUTH) {
                z = 0 - a;
            }
            if (dir == Direction.NORTH) {
                z += a;
            }
            if (dir == Direction.EAST) {
                x = 0 - a;
            }
            if (dir == Direction.WEST) {
                x += a;
            }
            harvestPlane(world, player, dir, new BlockPos(centralPos).offset(x, y, z), effectiveMaterials, planeRadius, harvestLevelCheck, excludedBlock, tool, toolDamageConsumer);
        }
    }

    public static void harvestPlane(Level world, Player player, Direction dir, BlockPos pos, Set<MapColor> effectiveMaterials, int radius, boolean harvestLevelCheck, @Nullable BlockPos excludedBlock, ItemStack tool, BiConsumer<BlockPos, BlockState> toolDamageConsumer) {
        int fortuneLevel = EnchantmentHelper.getItemEnchantmentLevel(Enchantments.BLOCK_FORTUNE, player.getUseItem());
        int silkLevel = EnchantmentHelper.getItemEnchantmentLevel(Enchantments.SILK_TOUCH, player.getUseItem());
        int supRad = (radius - 1) / 2;
        for (int a = -supRad; a <= supRad; a++) {
            for (int b = -supRad; b <= supRad; b++) {
                BlockPos target = null;
                if (dir == Direction.UP || dir == Direction.DOWN) {
                    target = pos.offset(a, 0, b);
                }
                if (dir == Direction.NORTH || dir == Direction.SOUTH) {
                    target = pos.offset(a, b, 0);
                }
                if (dir == Direction.EAST || dir == Direction.WEST) {
                    target = pos.offset(0, a, b);
                }
                if (excludedBlock == null || target == null || !target.equals(excludedBlock)) {
                    attemptBreak(world, target, player, Sets.newHashSet(), effectiveMaterials, fortuneLevel, silkLevel, harvestLevelCheck, tool, toolDamageConsumer);
                }
            }
        }
    }

    public static void attemptBreak(Level world, BlockPos pos, Player player, Set<Block> effectiveOn, Set<MapColor> effectiveMaterials, int fortuneLevel, int silkLevel, boolean checkHarvestLevel, ItemStack tool, BiConsumer<BlockPos, BlockState> toolDamageConsumer) {
        BlockState state = world.getBlockState(pos);
        var iCertainlyHopeYouHaveATileEntityLicense = world.getBlockEntity(pos);
        boolean validHarvest = !checkHarvestLevel || player.getUseItem().isCorrectToolForDrops(state);

        boolean isEffective = effectiveOn.contains(state.getBlock()) || effectiveMaterials.contains(state.getMapColor(world,pos));
        boolean witherImmune = "BlockTags.WITHER_IMMUNE.contains(state.getBlock())" .length()>0|| state.getBlock() == Blocks.SPAWNER;
        if (validHarvest && isEffective && !witherImmune) {
            world.destroyBlock(pos, false);
            Block.dropResources(state, world, pos, iCertainlyHopeYouHaveATileEntityLicense, player, player.getUseItem());
            toolDamageConsumer.accept(pos, state);
            int exp = state.getExpDrop(world, RandomSource.create(), pos, fortuneLevel, silkLevel);
            if (exp > 0 && (world instanceof ServerLevel)) {
                state.getBlock().popExperience((ServerLevel) world, pos, exp);
            }
        }
    }
}